package com.choudou5.tools.spider;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.alibaba.excel.EasyExcel;
import com.alibaba.fastjson.JSON;
import com.choudou5.tools.excel.BasicExcelHelper;
import lombok.extern.slf4j.Slf4j;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;

import java.io.File;
import java.net.URL;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * @name：当当网书籍
 * @author：xuhaowen
 * @date：2021-11-10
 */
@Slf4j
public class DangDangBookRepairUtil extends BasicExcelHelper  {

    public static void main(String[] args) throws Exception {
        String filePath = "C:\\Users\\admin\\Documents\\WeChat Files\\xuhaowende\\FileStorage\\File\\2021-11\\book333.xlsx";
        // wiki https://www.yuque.com/easyexcel/doc/read
        List<BookBeanVo> data = EasyExcel.read(filePath).head(BookBeanVo.class).sheet(0).doReadSync();
        int dex = 0;
        for (BookBeanVo bookBean : data) {
            dex++;
            if(StrUtil.isNotBlank(bookBean.getYear()) && StrUtil.isNotBlank(bookBean.getCategory())){
                System.out.println("跳过："+dex);
                continue;
            }
            getBookBeanVo(bookBean);
            System.out.println(JSON.toJSONString(bookBean));
            int rand = RandomUtil.randomInt(1000, 2000);
            System.out.println(dex+" 随机休眠："+rand);
            Thread.currentThread().sleep(rand);
        }
        String newFilePath = "D:\\书籍日期与分类666.xlsx";
        //导出Excel
        EasyExcel.write(newFilePath, BookBeanVo.class).sheet("新数据").doWrite(data);
    }

    private static void getBookBeanVo(BookBeanVo vo) {
        String detailUrl = null;
        try {
            Document doc = Jsoup.parse(new URL("http://search.dangdang.com/?key="+vo.getIsbn()), 2000);
            if(StrUtil.isBlank(vo.getYear())){
                parseYear(doc, vo, 1);
            }
            //重试第二行
            if(StrUtil.isBlank(vo.getYear())){
                parseYear(doc, vo, 2);
            }
            detailUrl = selectAttrValue(doc, ".bigimg li:nth-child(1) > a", "href");
//        System.out.println(detailUrl);
        } catch (Exception e) {
            System.out.println("日期爬取失败:"+e.getMessage());
        }
        if(StrUtil.isBlank(vo.getCategory())){
            String category = findBookCategory(detailUrl);
            vo.setCategory(ObjectUtil.defaultIfNull(category, ""));
        }
    }

    private static void parseYear(Document doc, BookBeanVo vo, int dex){
        String year = selectText(doc, ".bigimg li:nth-child("+dex+") > p.search_book_author > span:nth-child(2)");
        if(StrUtil.isNotBlank(year)) {
            year = year.replace("/", "");
            vo.setYear(ObjectUtil.defaultIfNull(year, ""));
        }
    }

    private static String findBookCategory(String detailUrl) {
        if(detailUrl == null)
            return null;
        String category = null;
        try {
            Document doc = Jsoup.parse(new URL("http:"+detailUrl), 2000);
            category = selectText(doc, "#breadcrumb a");
            if(StrUtil.isNotBlank(category)){
                category = category.substring(3).replace("   ", "").replace(" ", ">");
            }
        } catch (Exception e) {
            System.out.println("分类爬取失败："+e.getMessage());
        }
//        System.out.println(category);
        return category;
    }


    private static void wirteFile(String newFileName, List<Map> newList){
        File newFile = new File(newFileName);
        ExcelWriter writer = ExcelUtil.getWriter(newFile);
        Map<String, String> headerAlias = new LinkedHashMap<>();
        headerAlias.put("isbn", "isbn及虚拟书号");
        headerAlias.put("year", "年份");
        headerAlias.put("category", "分类");
        writer.setHeaderAlias(headerAlias);
        writer.write(newList);
        writer.flush();
        writer.close();
    }

    private static String selectText(Document doc, String rule){
        Elements ele = doc.select(rule);
        return ele.text();
    }

    private static String selectAttrValue(Document doc, String rule, String attrName){
        Elements ele = doc.select(rule);
        return ele.attr(attrName);
    }


    private static void selectPrintHtml(Document doc, String rule){
        Elements ele = doc.select(rule);
        System.out.println(ele.html());
    }

}
